package com.zk.bytecode.intercept;

import com.zk.bytecode.trace.TraceInterceptor;
import net.bytebuddy.asm.Advice;
import net.bytebuddy.build.Plugin;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.dynamic.ClassFileLocator;
import net.bytebuddy.dynamic.DynamicType;
import net.bytebuddy.matcher.ElementMatchers;

import java.io.IOException;

public class InterceptorPlugin implements Plugin {
    /**
     * Applies this plugin.
     *
     * @param builder          The builder to use as a basis for the applied transformation.
     * @param typeDescription  The type being transformed.
     * @param classFileLocator A class file locator that can locate other types in the scope of the project.
     * @return The supplied builder with additional transformations registered.
     */
    @Override
    public DynamicType.Builder<?> apply(DynamicType.Builder<?> builder, TypeDescription typeDescription, ClassFileLocator classFileLocator) {
        return builder.visit(Advice.
                to(TraceInterceptor.class).
                on(ElementMatchers
                        .anyOf(ElementMatchers.named("create"))
                ));
    }

    /**
     * Closes this stream and releases any system resources associated
     * with it. If the stream is already closed then invoking this
     * method has no effect.
     *
     * <p> As noted in {@link AutoCloseable#close()}, cases where the
     * close may fail require careful attention. It is strongly advised
     * to relinquish the underlying resources and to internally
     * <em>mark</em> the {@code Closeable} as closed, prior to throwing
     * the {@code IOException}.
     *
     * @throws IOException if an I/O error occurs
     */
    @Override
    public void close() throws IOException {

    }

    /**
     * Matches a target against this element matcher.
     *
     * @param target The instance to be matched or {@code null}.
     * @return {@code true} if the given element is matched by this matcher or {@code false} otherwise.
     */
    @Override
    public boolean matches(TypeDescription target) {
        if (target == null || target.getName().startsWith("java")) {
            return false;
        }
        return true;
    }
}
